<?php
// Little-endian based LONG/WORD/BYTE macros

function MAKEWORD($a, $b) {
	return ((($a & 0x000000ff)) | ((($b & 0x000000ff))) << 8);
}


function MAKELONG($a, $b) {
	return (($a & 0x0000ffff) | ($b & 0x0000ffff) << 16);
}


function LOWORD($l) {
	return ($l & 0x0000ffff);
}


function HIWORD($l) {
	return ($l >> 16);
}


function LOBYTE($w) {
	return ($w & 0x000000ff);
}


function HIBYTE($w) {
	return ($w >> 8);
}

// PHP Read Macros

function READ_COLOR_REF (&$stream, &$color) {
	
	$colorref = READ_INTEGER ($stream);
	
	$color[0] = LOBYTE(LOWORD($colorref));
	$color[1] = HIBYTE(LOWORD($colorref));
	$color[2] = LOBYTE(HIWORD($colorref));
}

function WRITE_COLOR_REF (&$stream, &$color) {
	
	$colorref = MAKELONG(MAKEWORD($color[0], $color[1]), MAKEWORD($color[2], 0));
	
	return WRITE_INTEGER ($stream,$colorref);
	
}

function READ_BYTE (&$stream) {
    return array_pop(unpack("C", fread($stream->GetStream (),1)));
}

function WRITE_BYTE (&$stream,$data) {
    return fwrite($stream->GetStream (),pack("C", $data), 1);
}

function READ_INIT8 (&$stream) {
    return array_pop(unpack("c", fread($stream->GetStream (),1)));
}

function WRITE_INIT8 (&$stream,$data) {
    return fwrite($stream->GetStream (),pack("c", $data), 1);
}

function READ_WORD (&$stream) {
    return array_pop(unpack("S", fread($stream->GetStream (), 2)));
}

function WRITE_WORD (&$stream,$data) {
    return fwrite($stream->GetStream (),pack("S", $data), 2);
}

function READ_INTEGER (&$stream) {
    return array_pop(unpack("I", fread($stream->GetStream (), 4)));
}

function WRITE_INTEGER (&$stream,$data) {
    return fwrite($stream->GetStream (),pack("I", $data), 4);
}

function READ_MFC_RECT (&$stream,&$rect) {
	
	for ($i=0;$i<4;++$i)
		$rect[$i] = READ_SIGNED_INTEGER ($stream);
		
}

function WRITE_MFC_RECT (&$stream,&$rect) {
	
	for ($i=0;$i<4;++$i)
		WRITE_SIGNED_INTEGER ($stream,$rect[$i]);
		
}

function READ_SIGNED_INTEGER (&$stream) {
    return array_pop(unpack("i", fread($stream->GetStream (), 4)));
}

function WRITE_SIGNED_INTEGER (&$stream,$data) {
    return fwrite($stream->GetStream (),pack("i", $data), 4);
}

function READ_CSTRING (&$stream) {
    $size = array_pop(unpack("C", fread($stream->GetStream (),1)));
    if ($size == 255)
    $size = array_pop(unpack("S", fread($stream->GetStream (),2)));
    if ($size == 65535)
    $size = array_pop(unpack("I", fread($stream->GetStream (),4)));
    if ($size > 0)
    return array_pop(unpack("A$size", fread($stream->GetStream (),$size)));
}

function WRITE_CSTRING (&$stream,$data) {
	
	$size = strlen($data);
	
	if ($size < 255)
		WRITE_BYTE ($stream,$size);
	elseif ($size < 65535) {
		WRITE_BYTE ($stream,0xff);
		WRITE_WORD ($stream,$size);
	}
	else {
		WRITE_BYTE ($stream,0xff);
		WRITE_BYTE ($stream,65535);
		WRITE_INTEGER ($stream,$size);
	}
	
	if ($size > 0)
		fwrite($stream->GetStream (),pack("A$size", $data), $size);
		
	return 1;
	
}

function READ_CSTRING_SECTION (&$stream) {
    $size = array_pop(unpack("S", fread($stream->GetStream (),2)));
    if ($size > 0)
    return array_pop(unpack("A$size", fread($stream->GetStream (),$size)));
}

function WRITE_CSTRING_SECTION (&$stream,$data) {
	
	$size = strlen ($data);
	
	WRITE_WORD ($stream,$size);
	
	if ($size > 0)
		fwrite($stream->GetStream (),pack("A$size", $data), $size);
		
}
	
	

?>